﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Hbrs.Soa.Restclient.Properties;
using System.Reflection;
using System.Globalization;
using Hbrs.Soa.Restclient.WadlToCode;
using Hbrs.Soa.Restclient.CodeToWadl;

namespace Hbrs.Soa.Restclient
{
    class Program
    {
        #region private methods

        private static Dictionary<string, string> GetDefaultArguments()
        {
            Dictionary<string, string> arguments = new Dictionary<string, string>();
            arguments.Add("language", "CS");
            arguments.Add("namespace", "CodeGeneratedFromWadl");
            arguments.Add("out", String.Empty);
            return arguments;
        }

        private static Dictionary<string, string> GetArguments(string[] args)
        {
            Dictionary<string, string> arguments = GetDefaultArguments();
            foreach (string arg in args)
            {
                string[] uarg = arg.Split(':');
                switch (uarg[0].ToLowerInvariant())
                {
                    case "/l":
                    case "/language":
                        arguments["language"] = uarg[1];
                        break;
                    case "/n":
                    case "/namespace":
                        arguments["namespace"] = uarg[1];
                        break;
                    case "/nobanner":
                        arguments["nobanner"] = String.Empty;
                        break;
                    case "/o":
                    case "/out":
                        arguments["out"] = String.Join(":", uarg, 1, uarg.Length - 1);
                        break;
                    default:
                        // Argument is unknown (yet)
                        if (uarg.Length > 1)
                        {
                            arguments[uarg[0].Replace("/", String.Empty)] = uarg[1];
                        }
                        break;
                }
            }
            return arguments;
        }

        private static void PrintBanner()
        {
            Console.WriteLine(Resources.TextHeader);
            Console.WriteLine(Resources.TextLicenseInfo);
        }

        private static void PrintHelp()
        {
            Console.WriteLine(Resources.TextErrorInvalidFilename);
            Console.WriteLine(Resources.TextInfoUsage);
        }

        private static void GenerateWadlFromAssembly(string inputFilename, Dictionary<string, string> args)
        {
            Assembly asm = null;
            try
            {
                asm = Assembly.LoadFrom(inputFilename);
            }
            catch (Exception ex)
            {
                Console.WriteLine(Resources.TextErrorLoadingAssembly, ex.Message);
            }
            GenerateWadlFromAssembly(asm, args);
        }

        private static void GenerateWadlFromAssembly(Assembly asm, Dictionary<string, string> args)
        {
            try
            {
                CodeToWadlGenerator gen = new CodeToWadlGenerator();
                gen.CreateServiceDescription(asm, args["out"]);
            }
            catch (Exception ex)
            {
                Console.WriteLine(Resources.TextErrorGeneratingWadl, ex.Message);
            }
        }

        private static void GenerateCodeFromWadl(string inputFilename, Dictionary<string, string> args)
        {
            string language = args["language"];
            string outdir = args["out"];
            WadlToCodeGenerator gen = new WadlToCodeGenerator(inputFilename, args["namespace"]);
            gen.GetGeneratedCodeAsFile(GeneratedFileType.ResourceClass, outdir, language);
            gen.GetGeneratedCodeAsFile(GeneratedFileType.ServiceContract, outdir, language);
            gen.GetGeneratedCodeAsFile(GeneratedFileType.ServiceClient, outdir, language);
            gen.CreateDefaultConfigFile(outdir);
        }

        #endregion

        static void Main(string[] args)
        {
            Dictionary<string, string> arguments = GetArguments(args);
            if (!arguments.ContainsKey("nobanner"))
            {
                PrintBanner();
            }
            if (args.Length > 0)
            {
                string inputFilename = args[0];
                if (File.Exists(inputFilename))
                {
                    string extension = Path.GetExtension(inputFilename).ToUpperInvariant();
                    switch (extension)
                    {
                        case ".WADL":
                            GenerateCodeFromWadl(inputFilename, arguments);
                            break;

                        case ".EXE":
                        case ".DLL":
                            GenerateWadlFromAssembly(inputFilename, arguments);
                            break;

                        default:
                            Console.WriteLine(Resources.TextErrorUnknownFileExtension, extension);
                            break;
                    }
                }
                else
                {
                    Console.WriteLine(Resources.TextErrorFileDoesNotExist, inputFilename);
                }
            }
            else
            {
                PrintHelp();
            }
        }
    }
}
